#include <iostream>
#include <windows.h>

#include "libpan.hpp"
#include "libpan_vars.hpp"

using namespace std;

bool IsConnected()
{
	return connected;
}

bool IsInChannel()
{
	return in_channel;
}

bool IsLoggedIn()
{
	return logged_in;
}

char *GetChannelName()
{
	return channel_name;
}

char *GetChannelRule()
{
	return channel_rule;
}

char *GetCharacterClanName()
{
	return character_clan_name;
}

char *GetCharacterName()
{
	return character_name;
}

char *GetINIContents()
{
	return ini_contents;
}

char *GetPassword()
{
	return server_password;
}

char *GetServerIP()
{
	return server_ip;
}

char *GetServerName()
{
	return server_name;
}

char GetServerType()
{
	return server_type;
}

char *GetUsername()
{
	return server_username;
}

GunZPacket::GunZPacket()
{
	memset(this->packet, 0, sizeof(this->packet));
	SetCurrentPacketID(GetCurrentPacketID() + 1);

	this->index = GUNZPACKET_HEADER_SIZE + GUNZPACKET_DATA_HEADER_SIZE;
	this->SetType(GUNZPACKET_ENCRYPTED);
	this->SetPacketID(GetCurrentPacketID());
	this->SetDataSize(GUNZPACKET_DATA_HEADER_SIZE);
	this->SetPacketSize(GUNZPACKET_HEADER_SIZE + GUNZPACKET_DATA_HEADER_SIZE);
}

int ChannelChat(unsigned long player_id, unsigned long channel_id, char *buf)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(CHANNEL_REQUEST_CHAT);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&channel_id), sizeof(channel_id));

	unsigned short buf_size = strlen(buf) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&buf_size), sizeof(buf_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(buf), strlen(buf));
	packet->WriteBytes(0, sizeof(unsigned short));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int CreateCharacter(unsigned long player_id, unsigned int index, char *name, unsigned int sex, unsigned int hair, unsigned int face, unsigned int costume)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(MATCH_REQUESTCREATECHAR);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&index), sizeof(index));

	unsigned short name_size = strlen(name) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&name_size), sizeof(name_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(name), strlen(name));
	packet->WriteBytes(0, sizeof(unsigned short));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&sex), sizeof(sex));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&hair), sizeof(hair));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&face), sizeof(face));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&costume), sizeof(costume));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int CreateRoom(unsigned long player_id, char *name, bool private_room, char *password)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(STAGE_CREATE);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));

	unsigned short name_size = strlen(name) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&name_size), sizeof(name_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(name), strlen(name));
	packet->WriteBytes(0, sizeof(unsigned short));

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&private_room), sizeof(private_room));

	if(private_room)
	{
		unsigned short password_size = strlen(password) + 2;

		packet->WriteBytes(reinterpret_cast<unsigned char *>(&password_size), sizeof(password_size));
		packet->WriteBytes(reinterpret_cast<unsigned char *>(password), strlen(password));
		packet->WriteBytes(0, sizeof(unsigned short));
	}
	else
	{
		unsigned short password_size = 2;

		packet->WriteBytes(reinterpret_cast<unsigned char *>(&password_size), sizeof(password_size));
		packet->WriteBytes(0, sizeof(unsigned short));
	}

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int DeleteCharacter(unsigned long player_id, unsigned int index, char *name)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(MATCH_REQUESTDELETECHAR);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&index), sizeof(index));

	unsigned short name_size = strlen(name) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&name_size), sizeof(name_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(name), strlen(name));
	packet->WriteBytes(0, sizeof(unsigned short));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int _stdcall DllMain(unsigned long base_address, unsigned long reason, unsigned long reserved)
{
	if(reason == DLL_PROCESS_ATTACH)
		InitializeCriticalSection(&cs);

	else if(reason == DLL_PROCESS_DETACH)
		DeleteCriticalSection(&cs);

	return 1;
}

int GetChannelPlayerList(unsigned long player_id, unsigned long channel_id, int page)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(CHANNEL_REQUESTPLAYERLIST);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&channel_id), sizeof(channel_id));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&page), sizeof(page));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int GetChannelType()
{
	return channel_type;
}

int GetCharacterList()
{
	GunZPacket *packet = new GunZPacket();
	packet->SetCommandID(MATCH_REQUESTACCOUNTCHARLIST);

	unsigned char parameters[] =
	{
		0x1C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	
	packet->WriteBytes(parameters, sizeof(parameters));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int GetMD5Size()
{
	return md5_size;
}

int GetRecommendedChannel()
{
	GunZPacket *packet = new GunZPacket();
	packet->SetCommandID(MATCHSERVER_REQUESTRECOMMENDEDCHANNEL);

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int JoinChannel(unsigned long player_id, unsigned long channel_id)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(CHANNEL_JOIN);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&channel_id), sizeof(channel_id));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int JoinPrivateRoom(unsigned long player_id, unsigned long stage_id, char *password)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(STAGE_REQUESTPRIVATEJOIN);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&stage_id), sizeof(stage_id));

	unsigned short password_size = strlen(password) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&password_size), sizeof(password_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(password), strlen(password));
	packet->WriteBytes(0, sizeof(unsigned short));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int JoinRoom(unsigned long player_id, unsigned long stage_id)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(STAGE_REQUESTJOIN);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&stage_id), sizeof(stage_id));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int Login(char *username, char *password, unsigned long long checksum, unsigned char *md5, unsigned short md5_size)
{
	GunZPacket *packet = new GunZPacket();
	packet->SetCommandID(MATCH_LOGIN);

	unsigned short username_size = strlen(username) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&username_size), sizeof(username_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(username), strlen(username));
	packet->WriteBytes(0, sizeof(unsigned short));

	unsigned short password_size = strlen(password) + 2;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&password_size), sizeof(password_size));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(password), strlen(password));
	packet->WriteBytes(0, sizeof(unsigned short));

	int version = GUNZPACKET_COMMAND_VERSION;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&version), sizeof(version));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&checksum), sizeof(checksum));

	unsigned long long md5_header = 0x1000000001;

	packet->WriteBytes(reinterpret_cast<unsigned char *>(&md5_header), sizeof(md5_header));
	packet->WriteBytes(md5, md5_size);

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int Pong(unsigned int time)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetType(GUNZPACKET_DECRYPTED);
	packet->SetCommandID(NET_PONG);
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&time), sizeof(time));
	packet->CalculateChecksum(packet->GetPacketSize());

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), packet->GetPacketSize());
	delete packet;

	return retn;
}

int SelectCharacter(unsigned long player_id, unsigned int index)
{
	GunZPacket *packet = new GunZPacket();

	packet->SetCommandID(MATCH_REQUESTSELECTCHAR);
	packet->WriteBytes(0, sizeof(unsigned long));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&player_id), sizeof(player_id));
	packet->WriteBytes(reinterpret_cast<unsigned char *>(&index), sizeof(index));

	unsigned short size = packet->GetPacketSize();

	packet->Encrypt(GetKey());
	packet->CalculateChecksum(size);

	int retn = GetMatchSocket()->Send(reinterpret_cast<char *>(packet->GetPacket()), size);
	delete packet;

	return retn;
}

int TCPSocket::Close()
{
	return closesocket(this->sock);
}

int TCPSocket::Connect(char *ip, unsigned short port)
{	
	hostent *host = gethostbyname(ip);
	sockaddr_in address;
	
	if(!host)
		return -1;
		
	address.sin_addr.s_addr = *reinterpret_cast<unsigned int *>(host->h_addr_list[0]);	
	address.sin_family = AF_INET;
	address.sin_port = htons(port);

	return connect(this->sock, reinterpret_cast<sockaddr *>(&address), sizeof(address));
}

int TCPSocket::GetLastError()
{
	return WSAGetLastError();
}

int TCPSocket::Receive(char *buf, int size)
{
	return recv(this->sock, buf, size, 0);
}

int TCPSocket::Send(char *buf, int size)
{
	return send(this->sock, buf, size, 0);
}

TCPSocket *GetMatchSocket()
{
	return match_socket;
}

TCPSocket::~TCPSocket()
{
	this->Close();
}

TCPSocket::TCPSocket()
{
	this->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}

unsigned char GetCharacterFace()
{
	return character_face;
}

unsigned char GetCharacterHair()
{
	return character_hair;
}

unsigned char GetCharacterIndex()
{
	return character_index;
}

unsigned char GetCharacterLevel()
{
	return character_level;
}

unsigned char GetCharacterSex()
{
	return character_sex;
}

unsigned char GetCurrentPacketID()
{
	return packet_id;
}

unsigned char *GetKey()
{
	return key_xchg;
}

unsigned char *GetMD5()
{
	return server_md5;
}

unsigned char GetPlayerPGrade()
{
	return player_pgrade;
}

unsigned char GetPlayerUGrade()
{
	return player_ugrade;
}

unsigned char *GunZPacket::GetPacket()
{
	return this->packet;
}

unsigned char GunZPacket::GetPacketID()
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);

	return data_header->packet_id;
}

unsigned int GetCharacterBP()
{
	return character_bp;
}

unsigned int GetCharacterClanGrade()
{
	return character_clan_grade;
}

unsigned int GetCharacterXP()
{
	return character_xp;
}

unsigned long GetChannelID()
{
	return channel_id;
}

unsigned long GetPlayerID()
{
	return player_id;
}

unsigned long long GetChecksum()
{
	return server_checksum;
}

unsigned short GetCharacterMaxAP()
{
	return character_max_ap;
}

unsigned short GetCharacterMaxHP()
{
	return character_max_hp;
}

unsigned short GetServerPort()
{
	return server_port;
}

unsigned short GunZPacket::GetChecksum()
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);

	return packet_header->checksum;
}

unsigned short GunZPacket::GetCommandID()
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);

	return data_header->command_id;
}

unsigned short GunZPacket::GetDataSize()
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);

	return data_header->size;
}

unsigned short GunZPacket::GetPacketSize()
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);

	return packet_header->size;
}

unsigned short GunZPacket::GetType()
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);

	return packet_header->type;
}

void CopySubstring(char *input, char *from, char *to, char *output)
{
	_snprintf(output, (strstr((strstr(input, from) + strlen(from)), to) - (strstr(input, from) + strlen(from))), (strstr(input, from) + strlen(from)));
}

void ExtractFromINI(char *ini_contents, char *section, char *element, char *buf)
{
	CopySubstring(strstr(ini_contents, section), element, "\n", buf);
}

void GetProgramDirectory(char *buf, int size)
{
	GetModuleFileName(GetModuleHandle(0), buf, size);

	for(int i = strlen(buf); i; i--)
	{
		if(buf[i] == '\\')
		{
			buf[i] = 0;

			break;
		}
		else
			buf[i] = 0;
	}
}

void GunZPacket::CalculateChecksum(unsigned short size)
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);
	packet_header->checksum = 0;

	for(int i = 6; i < size; i++)
		packet_header->checksum += this->packet[i];
	
	for(int i = 0; i < 4; i++)
		packet_header->checksum -= this->packet[i];
}

void GunZPacket::Decrypt(unsigned char *key)
{
	this->packet[2] = (((this->packet[2] ^ 0xF0) >> 3) | (((this->packet[2] ^ 0xF0) & 7) << 5)) ^ key[0 % 0x20];
	this->packet[3] = (((this->packet[3] ^ 0xF0) >> 3) | (((this->packet[3] ^ 0xF0) & 7) << 5)) ^ key[1 % 0x20];

	for(int i = 0; i < (int)(this->GetPacketSize() - GUNZPACKET_HEADER_SIZE); ++i)
		this->packet[i + 6] = (((this->packet[i + 6] ^ 0xF0) >> 3) | (((this->packet[i + 6] ^ 0xF0) & 7) << 5)) ^ key[i % 0x20];
}

void GunZPacket::Encrypt(unsigned char *key)
{
	this->packet[2] = (((this->packet[2] ^ key[0 % 0x20]) >> 5) | (((this->packet[2] ^ key[0 % 0x20]) << 3) & 0xFF)) ^ 0xF0;
	this->packet[3] = (((this->packet[3] ^ key[1 % 0x20]) >> 5) | (((this->packet[3] ^ key[1 % 0x20]) << 3) & 0xFF)) ^ 0xF0;

	for(int i = 0; i < this->GetDataSize(); ++i)
		this->packet[i + 6] = (((this->packet[i + 6] ^ key[i % 0x20]) >> 5) | (((this->packet[i + 6] ^ key[i % 0x20]) << 3) & 0xFF)) ^ 0xF0;
}

void GunZPacket::FillPacket(unsigned char *buf, unsigned short size)
{
	memcpy(this->packet, buf, size);
}

void GunZPacket::GetBytes(unsigned char *buf, unsigned short size)
{
	memcpy(buf, this->GetPacket() + this->index, size);
	this->index += size;
}

void GunZPacket::ResetIndex()
{
	this->index = GUNZPACKET_HEADER_SIZE + GUNZPACKET_DATA_HEADER_SIZE;
}

void GunZPacket::SetCommandID(unsigned short id)
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);
	data_header->command_id = id;
}

void GunZPacket::SetDataSize(unsigned short size)
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);
	data_header->size = size;
}

void GunZPacket::SetPacketID(unsigned char id)
{
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);
	data_header->packet_id = id;
}

void GunZPacket::SetPacketSize(unsigned short size)
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);
	packet_header->size = size;
}

void GunZPacket::SetType(unsigned short type)
{
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);
	packet_header->type = type;
}

void GunZPacket::WriteBytes(unsigned char *buf, unsigned short size)
{
	if(buf)
		memcpy(this->packet + this->index, buf, size);

	else
		memset(this->packet + this->index, 0, size);

	this->index += size;
	
	GunZPacketHeader *packet_header = reinterpret_cast<GunZPacketHeader *>(this->packet);
	GunZPacketDataHeader *data_header = reinterpret_cast<GunZPacketDataHeader *>(this->packet + GUNZPACKET_HEADER_SIZE);

	data_header->size += size;
	packet_header->size = GUNZPACKET_HEADER_SIZE + data_header->size;
}

void Print(char *buf, ...)
{
	char buf2[SIZE_1K];
	va_list list;

	va_start(list, buf);
	_vsnprintf(buf2, sizeof(buf2) - 1, buf, list);
	va_end(list);

	EnterCriticalSection(&cs);
	cout << buf2;
	LeaveCriticalSection(&cs);
}

void SetChannelID(unsigned long id)
{
	channel_id = id;
}

void SetChannelName(char *name)
{
	channel_name = name;
}

void SetChannelRule(char *rule)
{
	channel_rule = rule;
}

void SetChannelType(int type)
{
	channel_type = type;
}

void SetCharacterBP(unsigned int bp)
{
	character_bp = bp;
}

void SetCharacterClanGrade(unsigned int grade)
{
	character_clan_grade = grade;
}

void SetCharacterClanName(char *name)
{
	character_clan_name = name;
}

void SetCharacterFace(unsigned char face)
{
	character_face = face;
}

void SetCharacterHair(unsigned char hair)
{
	character_hair = hair;
}

void SetCharacterIndex(unsigned char index)
{
	character_index = index;
}

void SetCharacterLevel(unsigned char level)
{
	character_level = level;
}

void SetCharacterMaxAP(unsigned short max_ap)
{
	character_max_ap = max_ap;
}

void SetCharacterMaxHP(unsigned short max_hp)
{
	character_max_hp = max_hp;
}

void SetCharacterName(char *name)
{
	character_name = name;
}

void SetCharacterSex(unsigned char sex)
{
	character_sex = sex;
}

void SetCharacterXP(unsigned int xp)
{
	character_xp = xp;
}

void SetChecksum(unsigned long long checksum)
{
	server_checksum = checksum;
}

void SetConnected(bool status)
{
	connected = status;
}

void SetCurrentPacketID(unsigned char id)
{
	if(packet_id == 0xFF)
		packet_id = 0;
		
	else
		packet_id = id;
}

void SetInChannel(bool status)
{
	in_channel = status;
}

void SetINIContents(char *buf)
{
	ini_contents = buf;
}

void SetKey(unsigned char *key)
{
	key_xchg = key;
}

void SetLoggedIn(bool status)
{
	logged_in = status;
}

void SetMatchSocket(TCPSocket *match)
{
	match_socket = match;
}

void SetMD5(unsigned char *md5)
{
	server_md5 = md5;
}

void SetMD5Size(int size)
{
	md5_size = size;
}

void SetPassword(char *password)
{
	server_password = password;
}

void SetPlayerID(unsigned long id)
{
	player_id = id;
}

void SetPlayerPGrade(unsigned char pgrade)
{
	player_pgrade = pgrade;
}

void SetPlayerUGrade(unsigned char ugrade)
{
	player_ugrade = ugrade;
}

void SetServerIP(char *ip)
{
	server_ip = ip;
}

void SetServerName(char *name)
{
	server_name = name;
}

void SetServerPort(unsigned short port)
{
	server_port = port;
}

void SetServerType(char type)
{
	server_type = type;
}

void SetUsername(char *username)
{
	server_username = username;
}

WS2::~WS2()
{
	WSACleanup();
}

WS2::WS2()
{
	WSADATA data;
	WSAStartup(MAKEWORD(2, 0), &data);
}